﻿@inject IUserBasketService basketService
@inject ISearchService searchService
@inject NavigationService navContext
@inject NavigationManager NavigationManager
@inject IUserConfigService configService
@inject IImageCacheService imageCache
@inject IUserService userService
@inject IRescanService rescanService
@inject ITagService tagService
@inject ILogger<ImageProperties> logger 

@inject IJSRuntime JsRuntime
@implements IDisposable

@if( CurrentImage == null )
{
    <div class="damselfly-imageproperties">
        <p>
            <em>Loading image properties...</em>
        </p>
    </div>
}
else
{
    <div @key="CurrentImage" class="damselfly-imageproperties">
        @if( basketService.CurrentBasket != null )
        {
            <div>Add to @basketService.CurrentBasket.Name: <input class="damselfly-checkbox" type="checkbox" @bind="@InBasket"/></div>
        }

        <ImageField FieldName="Date Taken" FieldValue="@CurrentImage.SortDate.Display()"/>
        <ImageField FieldName="Filename" FieldValue="@CurrentImage.FileName"/>
        <ImageField FieldName="Folder" FieldValue="@CurrentImage.Folder.Name" Title="@CurrentImage.Folder.Path" Href="@CurrentFolderLink"/>

        @if( CurrentImage.MetaData != null )
        {
            <ImageField FieldName="Caption" FieldValue="@CurrentImage.MetaData.Caption" Editable="true" OnValueChanged="@CaptionChanged"/>
            <ImageField FieldName="Description" FieldValue="@CurrentImage.MetaData.Description" Editable="true" OnValueChanged="@DescriptionChanged"/>
            <ImageField FieldName="Copyright" FieldValue="@CurrentImage.MetaData.Copyright" Editable="true" OnValueChanged="@CopyrightChanged"/>
            <ImageField FieldName="Credit" FieldValue="@CurrentImage.MetaData.Credit"/>
            <div class="imagefield">
                <label class="imagefield-label" title="@RatingTitle">
                    Rating:
                    <StarRating @bind-Rating="CurrentImage.MetaData.Rating" @bind-Rating:after="OnRatingChanged"/>
                </label>
            </div>
            <ImageField FieldName="Size" FieldValue="@Size"/>
            <ImageField FieldName="Camera" FieldValue="@Camera"/>
            <ImageField FieldName="Lens" FieldValue="@Lens"/>
            <ImageField FieldName="ISO" FieldValue="@CurrentImage.MetaData.ISO"/>
            <ImageField FieldName="Aperture" FieldValue="@Aperture"/>
            <ImageField FieldName="Exposure" FieldValue="@Exposure"/>
            <ImageField FieldName="GeoLocation" FieldValue="@Location"/>

            if( !string.IsNullOrEmpty(CurrentImage.MetaData.DominantColor) )
            {
                <div class="imagefield">
                    <label class="imagefield-label" title="Dominant Color">
                        Colors:
                        <span title="Dominant Colour" class="dominant-color" style="@DominantColorStyle"/>
                        <span title="Average Colour" class="dominant-color" style="@AverageColorStyle"/>
                    </label>
                </div>
            }
        }
        else
        {
            <div>No metadata available yet.</div>
        }
        @if( Expanded )
        {
            <div @onclick="@(() => CollapseDisplay())">
                Show Less... &nbsp;<i class="fas fa-chevron-up"/>
            </div>
        }
        else
        {
            <div @onclick="@(() => ExpandDisplay())">
                Show More... &nbsp; <i class="fas fa-chevron-down"/>
            </div>
        }
        @if( Expanded )
        {
            <ImageField FieldName="File Modified" FieldValue="@CurrentImage.FileLastModDate.Display()"/>
            <ImageField FieldName="Metadata Scanned:" FieldValue="@MetadataScanDate"/>
            <div>
                <ImageField FieldName="Thumbs Generated" FieldValue="@ThumbnailUpdate">
                    <AuthorizeView Policy="@PolicyDefinitions.s_IsEditor">
                        <ToolbarButton IconStyle="fa-sync-alt" OnClickCallback="@RefreshThumb" title="Regenerate thumbnail"/>
                    </AuthorizeView>
                </ImageField>
            </div>
            <div>
                <ImageField FieldName="AI Processed" FieldValue="@AIProcessDate">
                    <AuthorizeView Policy="@PolicyDefinitions.s_IsEditor">
                        <ToolbarButton IconStyle="fa-sync-alt" OnClickCallback="@RefreshAI" title="Re-run AI processing"/>
                    </AuthorizeView>
                </ImageField>
            </div>

            @if( CurrentImage.Hash != null )
            {
                <ImageField FieldName="Hash" FieldValue="@CurrentImage.Hash.MD5ImageHash"/>
            }
        }
    </div>
}

@code {
    public Image CurrentImage { get; set; }

    public string CurrentFolderLink => $"/?folderId={CurrentImage.Folder.FolderId}";
    public string Size => $"{CurrentImage.MetaData.Width} x {CurrentImage.MetaData.Height}";
    public string Camera => CurrentImage.MetaData.Camera != null ? $"{CurrentImage.MetaData.Camera.Make} {CurrentImage.MetaData.Camera.Model}" : string.Empty;
    public string Lens => CurrentImage.MetaData.Lens != null ? $"{CurrentImage.MetaData.Lens.Make} {CurrentImage.MetaData.Lens.Model}" : string.Empty;
    public string Exposure => !string.IsNullOrEmpty(CurrentImage.MetaData.Exposure) ? $"{CurrentImage.MetaData.Exposure} {(CurrentImage.MetaData.FlashFired ? "(flash)" : string.Empty)}" : string.Empty;
    public string Aperture => !string.IsNullOrEmpty(CurrentImage.MetaData.FNum) ? $"f{CurrentImage.MetaData.FNum}" : string.Empty;
    public string AverageColorStyle => $"background-color:{CurrentImage.MetaData.AverageColor}";
    public string DominantColorStyle => $"background-color:{CurrentImage.MetaData.DominantColor}";
    public string Location => CurrentImage.MetaData.Latitude.HasValue ? $"{CurrentImage.MetaData.Latitude:n6}, {CurrentImage.MetaData.Longitude:n6}" : string.Empty;
    public string RatingTitle => CurrentImage.MetaData?.Rating == 0 ? "Unrated" : $"Rating: {CurrentImage.MetaData?.Rating} stars";
    private bool Expanded { get; set; }

    private async Task ExpandDisplay()
    {
        Expanded = true;
        await configService.SetForUser("ShowExtendedProps", Expanded.ToString());
    }

    private async Task CollapseDisplay()
    {
        Expanded = false;
        await configService.SetForUser("ShowExtendedProps", Expanded.ToString());
    }

    public bool InBasket
    {
        get => basketService.IsInCurrentBasket(CurrentImage);
        set => _ = SetBasketState(value);
    }

    private async Task SetBasketState(bool newState)
    {
        await basketService.SetImageBasketState(newState, new[] { CurrentImage.ImageId });

        // Notify the image list that the selection has changed
        StateHasChanged();
    }

    private async Task OnRatingChanged()
    {
        var newValue = CurrentImage.MetaData.Rating;
        await tagService.SetExifFieldAsync(new[] { CurrentImage.ImageId }, ExifOperation.ExifType.Rating, newValue.ToString(), userService.UserId);
        CurrentImage.MetaData.Rating = newValue;
        StateHasChanged();
    }

    private async void CaptionChanged(ChangeEventArgs args)
    {
        var newValue = args.Value as string;

        if( CurrentImage.MetaData.Caption != newValue )
        {
            await tagService.SetExifFieldAsync(new[] { CurrentImage.ImageId }, ExifOperation.ExifType.Caption, newValue, userService.UserId);
            CurrentImage.MetaData.Caption = newValue;
            StateHasChanged();
        }
    }

    private async void DescriptionChanged(ChangeEventArgs args)
    {
        var newValue = args.Value as string;
        if( CurrentImage.MetaData.Description != newValue )
        {
            await tagService.SetExifFieldAsync(new[] { CurrentImage.ImageId }, ExifOperation.ExifType.Description, newValue, userService.UserId);
            CurrentImage.MetaData.Description = newValue;
            StateHasChanged();
        }
    }

    private async void CopyrightChanged(ChangeEventArgs args)
    {
        var newValue = args.Value as string;
        if( CurrentImage.MetaData.Copyright != newValue )
        {
            await tagService.SetExifFieldAsync(new[] { CurrentImage.ImageId }, ExifOperation.ExifType.Copyright, newValue, userService.UserId);
            CurrentImage.MetaData.Copyright = newValue;
            StateHasChanged();
        }
    }

    protected override async Task OnInitializedAsync()
    {
        Expanded = configService.GetBool("ShowExtendedProps");

        if( !Expanded )
            CollapseDisplay();

        navContext.OnChange += NavigationChanged;
        basketService.OnBasketChanged += BasketStateChanged;

        CurrentImage = navContext.CurrentImage;
    }

    public void Dispose()
    {
        navContext.OnChange -= NavigationChanged;
        basketService.OnBasketChanged -= BasketStateChanged;
    }

    protected void BasketStateChanged(BasketChanged change)
    {
        StateHasChanged();
    }

    protected void NavigationChanged(Image image)
    {
        if( CurrentImage == null || image == null || image.ImageId != CurrentImage.ImageId )
        {
            CurrentImage = image;

            StateHasChanged();
        }
    }

    public string ThumbnailUpdate
    {
        get
        {
            if( CurrentImage != null && CurrentImage.MetaData != null && CurrentImage.MetaData.ThumbLastUpdated.HasValue )
            {
                var age = DateTime.UtcNow - CurrentImage.MetaData.ThumbLastUpdated;

                return age.Value.ToHumanReadableString() + " ago";
            }

            return "Never";
        }
    }

    public string AIProcessDate
    {
        get
        {
            if( CurrentImage != null && CurrentImage.MetaData != null && CurrentImage.MetaData.AILastUpdated.HasValue )
            {
                var age = DateTime.UtcNow - CurrentImage.MetaData.AILastUpdated;

                return age.Value.ToHumanReadableString() + " ago";
            }

            return "Never";
        }
    }

    public string MetadataScanDate
    {
        get
        {
            if( CurrentImage != null && CurrentImage.MetaData != null && CurrentImage.MetaData.LastUpdated != DateTime.MinValue )
            {
                var age = DateTime.UtcNow - CurrentImage.MetaData.LastUpdated;

                return age.ToHumanReadableString() + " ago";
            }

            return "Never";
        }
    }

    public async Task RefreshThumb()
    {
        await rescanService.MarkImagesForRescan(RescanTypes.Thumbnails, new List<int> { CurrentImage.ImageId });
    }

    public async Task RefreshAI()
    {
        await rescanService.MarkImagesForRescan(RescanTypes.AI, new List<int> { CurrentImage.ImageId });
    }

}